home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX503 / HDX.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  58.9 KB  |  2,375 lines

  1. /* hdx.c */
  2.  
  3. /*
  4.  * Atari Hard Disk Installation Utility
  5.  * Copyright 1988 Atari Corp.
  6.  *
  7.  * Associated files
  8.  *    hdx.rsc        resource file
  9.  *    wincap        hard disk database (text file)
  10.  *
  11.  *    hdx.h        object tree definitions
  12.  *    defs.h        constant definitions
  13.  *    part.h        ST structure definitions
  14.  *    ipart.h        IBM structure definitions
  15.  *
  16.  *    hdx.c        top level, user interface (this file)
  17.  *    epart.c        edit partition sizes
  18.  *    fmt.c        disk formatting
  19.  *    part.c        partition reading/writing
  20.  *    sect.c        sector reading, writing, zeroing
  21.  *    string.c    string functions (matching, concat, ...)
  22.  *    assist.c    markbad(), zero()
  23.  *    wincap.c    hard disk parameter / partition size database
  24.  *    st.c        random ST functions (delay, reboot, ...)
  25.  *
  26.  *----
  27.  * 11-May-1988    ml.    Cleaned up the memory management in the program
  28.  *            (ie. for all files).  Memory chunks which are for
  29.  *            sure will be < 32k is allocated using malloc(),
  30.  *            whereas chunks >= 32k is allocated using Malloc().
  31.  *            When using malloc(), you will get the 'Stack Over-
  32.  *            flow message if you are in Supervisor mode and 
  33.  *            you have your own supervisor stack.  To get around
  34.  *            this, have to use mymalloc() (in mymalloc.s).
  35.  * 15-Mar-1988    ml.    Changed interface to Markbad.
  36.  * 11-Jan-1988    ml.    Modified dialogue boxes.
  37.  * 07-Dec-1987    ml.    Started to add in concept of Bad Sector List.
  38.  * ??-Oct-1987  ml.    Partition and Disk type menu now has 15 entries 
  39.  *            instead of 16.
  40.  * 30-Sep-1987    ml.    Inherited 'this' from Landon Dyer.
  41.  * 24-Mar-1986 lmd    Released to software test.
  42.  * 15-Mar-1986 lmd    Hacked up from earlier version by Jim Tittsler.
  43.  * 8-Nov-1988  jye. change and add some codes so that can be used for extended
  44.  *                    and big partition.
  45.  * 13-Jun-1989 jye. Change and add some codes so that HDX can be deal with
  46.  *                    acsi and scsi drives.
  47.  * 22-Jan-1990 jye. Change the HDX so that we don't have to put a informations
  48.  *                    of a drive into the Wincap file.
  49.  * 13-Mar-1990 jye. change the HDX to a genetic one so that the user don't
  50.  *                    need know what kind of drive.
  51.  * 20-Jul-1990 jye. change the interface about the unit select. In the new 
  52.  *                    interface, user tells the type of drive is acsi or scsi,
  53.  *                    then selects unit.
  54.  * 01-Aug-1990 jye. Change hard disk size request from mdsence to readcap.
  55.  * 25-Jul-1991 jye. Change the Hdx so that can be used for IDE-AT drive.
  56.  * 11-Nov-1991 jye. change the hdx so that can got the hard disk size from
  57.  *                    page 0, or 3, or 4, or from the wincap. For the SCSI drive,
  58.  *                    getting the disk size from wincap or readcap.
  59.  * 7-Jul-1992  jye. Change the hdx so that can be used for the sparrow scsi.
  60.  * Feb-3-1993  jye. Fixed a bug which is when format a hard disk with no wincap
  61.  *                    file, then the HDX will bomb out. Now, you can still format
  62.  *                    the hard disk without the wincap, because the wincap file
  63.  *                    is used when HDX can't get the hard disk's informations.
  64.  * Apr-9-1993  jye.    To fixed a problem for the Conner CP2088 drive, which HDX
  65.  *                    can't Markbad it in Format, because this kind of drive has
  66.  *                    the different values of head, cylinder, and spt between the
  67.  *                    physical and logical parameters, so I added a inqury() call
  68.  *                    right after the 'fmtunt()' in 'dodiform()' to up date the
  69.  *                    table, because 'fmtunt()' changes the physical parameters 
  70.  *                    to the logical parameters.
  71.  */
  72.  
  73. #include "obdefs.h"
  74. #include "gemdefs.h"
  75. #include "osbind.h"
  76. #include "mydefs.h"
  77. #include "part.h"
  78. #include "bsl.h"
  79. #include "hdx.h"
  80. #include "ipart.h"
  81. #include "addr.h"
  82. #include "myerror.h"
  83.  
  84. #define MFM 17
  85.  
  86. extern char sbuf[];
  87. extern int rebootp;
  88. extern long gbslsiz();
  89. extern long get3bytes();
  90. extern long get4bytes();
  91. extern long bslsiz;
  92. extern BYTE *bsl;
  93. extern int uplim;            /* the number of partitions */
  94. extern long sptrk;
  95. extern long spcyl;
  96. extern int ibmpart;
  97. extern int yesscan;
  98. extern long disksiz;
  99. extern long ratio;
  100. extern int typedev;
  101. extern int typedrv;
  102. extern int prevnpart;
  103. extern int atexst;        /* set for AT drive exist */
  104. extern int floptical;    /* set if it's a floptical drive */
  105.  
  106. /* Globals */
  107. int rebootp = 0;    /* 1: must reboot (not return to desktop) */
  108. int tformat;            /* TRUE: just formatted disk */
  109. int running;        /* 1: continue evnt_multi() loop */
  110. char sbuf[512];        /* error message buffer */
  111. long extsiz;        /* the size of extened partition */
  112. long ostack;        /* old stack pointer */
  113. int toibm;            /* the flag of partition to ibm format */
  114. int ibm2st;            /* the flag for IBM partition to ST */
  115. long bps;            /* bytes per sector */
  116. int npart;            /* number of partition */
  117. int ext;            /* the index of extended partition */
  118. int extend;            /* the index of end extended partition */
  119. int showmany;        /* the flag that show the too much device alert box */
  120. char ttscsi;        /* SCSI hard disk drive */
  121. char spscsixst;        /* set for sparrow scsi drive exist */
  122. int noacsi;            /* set for no ACSI dirve in the system */
  123. int needscan;        /* TRUE: if info in the LOGMAP update */
  124. int noinfo=1;            /* 1: no informations in the wincap */
  125. int athead;            /* the # of data heads on the AT drive */
  126. int atcyl;            /* the # of cylinders on the AT drive */
  127. int atspt;            /* the # of sectors per track on the AT drive */
  128. int ok2draw;        /* go ahead to draw the change part of dialog box */
  129. int ndevs;            /* the # of devices */
  130. char *drvid[] ={    /* for the id of the drives */
  131.     "123456789012345678901234567",
  132.     "123456789012345678901234567",
  133.     "123456789012345678901234567",
  134.     "123456789012345678901234567",
  135.     "123456789012345678901234567",
  136.     "123456789012345678901234567",
  137.     "123456789012345678901234567",
  138.     "123456789012345678901234567",
  139.     "123456789012345678901234567",
  140.     "123456789012345678901234567",
  141.     "123456789012345678901234567",
  142.     "123456789012345678901234567",
  143.     "123456789012345678901234567",
  144.     "123456789012345678901234567",
  145.     "123456789012345678901234567",
  146.     "123456789012345678901234567",
  147.     "123456789012345678901234567",
  148.     "Identification unavaliable",
  149.     "Not responding",
  150.     "ACSI 0",        /* index is 19 */
  151.     "ACSI 1",
  152.     "ACSI 2",
  153.     "ACSI 3",
  154.     "ACSI 4",
  155.     "ACSI 5",
  156.     "ACSI 6",
  157.     "ACSI 7",
  158.     "SCSI 0",        /* index is 27 */
  159.     "SCSI 1",
  160.     "SCSI 2",
  161.     "SCSI 3",
  162.     "SCSI 4",
  163.     "SCSI 5",
  164.     "SCSI 6",
  165.     "SCSI 7",
  166.     "IDE 0",            /* index is 35 */
  167.     " "
  168. };
  169.  
  170. DEVSET devid[17];
  171.  
  172. /*  Logical-to-dev+partition mapping table. */
  173. extern int nlogdevs;        /* #logical devs found */
  174. extern LOGMAP logmap[];        /* logical dev map */
  175. extern int livedevs[];        /* live physical dev flag */
  176. extern int idevs[];            /* the devise have a id */
  177. extern char cachexst;        /* 0: no cache. 1: with cache */
  178.  
  179. /* Partition related variables */
  180. long mxpsiz = MAXPSIZ;
  181.  
  182. /* AES (windows and messages) related variables */
  183. int gl_hchar;        /* height of system font (pixels) */
  184. int gl_wchar;        /* width of system font (pixels) */
  185. int gl_wbox;        /* width of box able to hold system font */
  186. int gl_hbox;        /* height of box able to hold system font */
  187.  
  188. int phys_handle;    /* physical workstation handle */
  189. int handle;        /* virtual workstation handle */
  190. int wi_handle;        /* window handle */
  191.  
  192. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  193. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  194. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  195.  
  196. int msgbuff[8];        /* event message buffer */
  197. int keycode;        /* keycode returned by event-keyboard */
  198. int mx, my;        /* mouse x and y pos. */
  199. int butdown;        /* button state tested for, UP/DOWN */
  200. int ret;        /* dummy return variable */
  201. int pnf;        /* 1: partition or format; 0: zero or markbad */
  202. int hidden;        /* current state of cursor */
  203. int contrl[12];
  204. int intin[128];
  205. int ptsin[128];
  206. int intout[128];
  207. int ptsout[128];    /* storage wasted for idiotic bindings */
  208. int work_in[11];    /* Input to GSX parameter array */
  209. int work_out[57];    /* Output from GSX parameter array */
  210. int pxyarray[10];    /* input point array */
  211. int blitxst;        /* the flag for check the BLiTTER */
  212.  
  213. /*
  214.  * Top level;
  215.  * we get control from the desktop.
  216.  */
  217. main()
  218. {
  219.     pnf = 0;        /* set the flag to it isn't partition yet */
  220.     appl_init();
  221.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  222.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  223.     open_vwork();
  224.     wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  225.  
  226.     hidden = FALSE;
  227.     butdown = TRUE;
  228.  
  229.     /* doing a checking see if the cache in the system */
  230.     cachexst = (char) chkcache();
  231.  
  232.     /* check the existence of the BLiTTER */
  233.     blitxst = chkblit();
  234.  
  235.     if (!rsrc_load(RESOURCEFILE)) {
  236.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  237.     goto punt;
  238.     }
  239.  
  240.     
  241.     /* Get all addresses of dialogues from resource file */
  242.     if (getalladdr() != OK) {
  243.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  244.     goto punt;
  245.     }
  246.  
  247.  
  248.     /*
  249.      * Get maximum partition size from
  250.      * wincap "@@" entry.
  251.      */
  252.     /*
  253.     if (wgetent("Parameters", "@@") == OK) {
  254.     if (wgetnum("ms", &mxpsiz) != OK)
  255.         mxpsiz = MAXPSIZ;
  256.     } else {
  257.         goto punt;
  258.     }
  259.     */
  260.  
  261.     needscan = TRUE;
  262.  
  263. redomul:
  264.     ARROW_MOUSE;
  265.  
  266.     /* display menu bar */
  267.     menu_bar(menuobj, 1);
  268.  
  269.     running = TRUE;
  270.     while (running) {
  271.         domulti();
  272.     }
  273.  
  274.     /*
  275.      * If nothing has been done to the hard disks
  276.      * then just get out, back to the desktop.
  277.      * Otherwise reboot the system.
  278.      */
  279.     menu_bar(menuobj, 0);        /* erase menu bar */
  280.  
  281. punt:
  282.     /*
  283.      * If we have to reboot,
  284.      * tell the user and then do it.
  285.      *
  286.      */
  287.     if (rebootp) {
  288.         if (form_alert(2, autoboot) == 1)    {
  289.             reboot();
  290.         } else {
  291.             goto redomul;
  292.         }
  293.     }
  294.  
  295.     wind_delete(wi_handle);
  296.     v_clsvwk(handle);
  297.     appl_exit();
  298. }
  299.  
  300.  
  301. /*
  302.  * Get a single event, process it, and return.
  303.  *
  304.  */
  305. domulti(){
  306.     int event;
  307.     
  308.     event = evnt_multi(MU_MESAG,
  309.             1,1,butdown,
  310.             0,0,0,0,0,
  311.             0,0,0,0,0,
  312.             msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  313.  
  314.     if (event & MU_MESAG) {
  315.         wind_update(TRUE);
  316.     switch (msgbuff[0]) {
  317.         case WM_REDRAW:
  318.         do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
  319.         break;
  320.  
  321.         case MN_SELECTED:
  322.             BEE_MOUSE;
  323.         switch(msgbuff[3]) {
  324.             case MNDISK:
  325.             switch (msgbuff[4]) {
  326.                 case DIFORM:
  327.                     if ((needscan) && (rescan(0,1) == ERROR))    {
  328.                         break;    /* don't report medium changed */
  329.                     }
  330.                     tformat = TRUE;
  331.                     needscan = FALSE;
  332.                     dodiform();
  333.                     tformat = FALSE;
  334.                     break;
  335.                 case DIPART:
  336.                     if ((needscan)&&(rescan(0,2) == ERROR))    {
  337.                         break;    /* don't report medium changed */
  338.                     }
  339.                     needscan = FALSE;
  340.                     dodipart(-1, NULL, NULL);
  341.                     break;
  342.                 case DIZERO:
  343.                     if (pnf)    {
  344.                         err(needboot);
  345.                     } else {
  346.                         if ((needscan)&&(rescan(0,0) == ERROR))    {
  347.                             break;    /* don't report medium changed */
  348.                         }
  349.                         needscan = FALSE;
  350.                         dodizero();
  351.                     }
  352.                     break;
  353.                 case DIMARK:
  354.                     if (pnf)    {
  355.                         err(needboot);
  356.                     } else {
  357.                         if ((needscan)&&(rescan(0,0) == ERROR))    {
  358.                             break;    /* don't report medium changed */
  359.                         }
  360.                         needscan = FALSE;
  361.                         dodimark();
  362.                     }
  363.                     break;
  364.                 /*
  365.                 case DISHIP:
  366.                     if ((needscan)&&(rescan(0,1) == ERROR))    {
  367.                         break; don't report medium changed
  368.                     }
  369.                     needscan = FALSE;
  370.                     dodiship();
  371.                     break;
  372.                 */
  373.                 default:        break;
  374.             }
  375.             break;
  376.  
  377.             case MNFILE:
  378.             switch (msgbuff[4]) {
  379.                 case FIQUIT:
  380.                 running = 0;
  381.                 break;
  382.  
  383.                 default:
  384.                 break;
  385.             }
  386.             break;
  387.             
  388.             case MNDESK:
  389.             if(msgbuff[4] == DEABOUT) {
  390.                 strcpy(abtdial[ABVERSN].ob_spec, "Version 5.03a");
  391.                  abtdial[ABOK].ob_state = NORMAL;
  392.                 execform(abtdial);
  393.             }
  394.             break;        /* "cannot happen" */
  395.         }
  396.  
  397.         menu_tnormal(menuobj, msgbuff[3], 1);    /* back to normal */
  398.             ARROW_MOUSE;
  399.         break;
  400.         
  401.         case WM_NEWTOP:
  402.         case WM_TOPPED:
  403.         wind_set(wi_handle, WF_TOP, 0, 0, 0, 0);
  404.         break;
  405.  
  406.         case WM_CLOSED:
  407.         running = FALSE;
  408.         break;
  409.  
  410.         default:
  411.         break;
  412.     }
  413.     wind_update(FALSE);
  414.     }
  415. }
  416.  
  417.  
  418. /*
  419.  * Default partition name (no "pt" entry).
  420.  */
  421. #define    DEF_PARTNAME    "4-6-10"
  422.  
  423.  
  424. /*
  425.  * Map from button in format dial.
  426.  */
  427. int pfmt[] = {
  428.     PFMT0, PFMT1, PFMT2, PFMT3,
  429.     PFMT4, PFMT5, PFMT6, PFMT7,
  430.     PFMT8, PFMT9, PFMT10, PFMT11,
  431.     PFMT12, PFMT13, PFMT14, PFMT15
  432. };
  433.  
  434.  
  435. /*
  436.  * Handle [FORMAT] item.
  437.  *
  438.  */
  439. dodiform()
  440. {
  441.   extern char bootstop;
  442.   extern char bootend;
  443.   int dev, v, w, i, br;
  444.   int modesel;            /* flag for mode select */
  445.   long cnt, hdsiz;
  446.   char *s, *d, *wgetstr();
  447.   char buf[10], bs[512], sendata[32];
  448.   char pnam[128];
  449.   char *seldev = "ACSI unit 0", *id = "XXXXX";
  450.   char *seldv =  "IDE  unit 0";
  451.   HINFO hinfo;
  452.   char devnames[NAMSIZ];    /* device type name buffer */
  453.   long nbad;
  454.   extern long gbslsiz(), nument(), dsmarkbad();
  455.   long pattern, temp, cyl;
  456.   long longrandom();
  457.   char pr_id[10];    /* partition scheme id */
  458.   int mask = 0x0001;
  459.   int set, scsidrv, bsiz, other = 0;
  460.   int page=4, spt, ret;
  461.   int head=0, domark=YESMK;
  462.   
  463.   /*
  464.    * Throw up generic formatting/partition warning,
  465.    * then get physical dev they want to clobber.
  466.    */
  467.   yesscan = 0;
  468.   noinfo = 1;
  469.   for (i = 0; i < NAMSIZ; i++)
  470.       devnames[i] = "\0";
  471.   fwarning[FWARNCN].ob_state = NORMAL;
  472.   fwarning[FWARNOK].ob_state = NORMAL;
  473.   if (execform(fwarning) != FWARNOK) return BAILOUT;
  474.  
  475.   if ((dev = gphysdev()) < 0) {
  476.       return BAILOUT;
  477.   }
  478.   strcpy(id, "mn");
  479.   br = 0;
  480.  
  481.   /* display doing SCSI massage */
  482.  
  483.   inqfmt:
  484.   /* Get all available disk types from wincap 'mn' entries */  
  485.   if (wallents(devnames, id) != OK)        {
  486.       goto stfm;
  487.   }
  488.   if (!*devnames)     {/* no informations */
  489.       goto stfm;
  490.   }
  491.   noinfo = 0;
  492.   /* Shove format name text into buttons */
  493.   for (i = 0, s = devnames; i < 14 && *s; ++i) {
  494.       dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  495.       dsknames[pfmt[i]].ob_spec = (long)s;
  496.       dsknames[pfmt[i]].ob_state = NORMAL;
  497.       dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  498.       while (*s++)
  499.     ;
  500.   }
  501.   other = i;                            /* the other button */
  502.   dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  503.   dsknames[pfmt[i]].ob_spec = "OTHER";
  504.   dsknames[pfmt[i]].ob_state = NORMAL;
  505.   dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  506.   i++;
  507.  
  508.   /* rest of buttons are invisible and untouchable */
  509.   for (; i < 16; ++i) {
  510.       dsknames[pfmt[i]].ob_type = G_IBOX;    /* invisible box */
  511.       dsknames[pfmt[i]].ob_spec = 0;        /* no thickness */
  512.       dsknames[pfmt[i]].ob_state = DISABLED;    /* nobody home */
  513.       dsknames[pfmt[i]].ob_flags = NONE;        /* disabled */
  514.   }
  515.   
  516.   /* clean up rest of the form and throw it up */
  517.   dsknames[PFOK].ob_state = NORMAL;
  518.   dsknames[PFCN].ob_state = NORMAL;
  519.   if (execform(dsknames) != PFOK)
  520.     return BAILOUT;
  521.   
  522.   /* search for format they picked */
  523.   for (i = 0; i < 18; ++i)
  524.     if (dsknames[pfmt[i]].ob_state & SELECTED)
  525.       break;
  526.   if (i >= 18) {        /* nothing picked */
  527.       return BAILOUT;
  528.   } else if (other == i)    {  /* the OTHER button was selected */
  529.         noinfo = 1;
  530.       goto stfm;
  531.   }
  532.   
  533.     if ((!br) && (dev < 8))        {
  534.           if (wgetent(dsknames[pfmt[i]].ob_spec, "mn") == ERROR)    {
  535.               strcpy(id, "mn");
  536.             noinfo = 1;
  537.             goto stfm;
  538.             /*
  539.             nofmt[NOSCHFMT].ob_spec = dsknames[pfmt[i]].ob_spec;
  540.             nofmt[NOSCHFMT].ob_state = NORMAL;
  541.             execform(nofmt, 0);
  542.             return ERROR;
  543.             */
  544.         }
  545.         if ((s = wgetstr("br")) != NULL)    {
  546.             strcpy(id, s);
  547.             br = 1;            /* processing the branch */
  548.             goto inqfmt;    /* start over */
  549.         }
  550.     }
  551.  
  552. stfm:
  553.     modesel = 1;
  554.   if(gfparm(dev, &noinfo, &modesel, &hinfo, dsknames[pfmt[i]].ob_spec,id)!= 0) {
  555.       return ERROR;
  556.   }
  557.   
  558.   /* get data pattern to test the disk */
  559.   if (wgetnum("dp", &pattern) != OK) {
  560.       pattern = longrandom();  /* can't find pattern from wincap, make one */
  561.   } else {
  562.       temp = pattern;
  563.       pattern <<= 16;    /* shift pattern to hi word */
  564.       pattern |= temp;
  565.   }
  566.  
  567.   if (dev > 15)    { /* IDE-AT drive */
  568.       br = dev - 16;
  569.   } else {            /* it is a scsi or acsi drive */
  570.       br = (dev > 7) ? (dev-8) : (dev);    /* minus 8 for the scsi drive number */
  571.   }
  572.  
  573.   /* asking the user do the marking bad or not */
  574.   mkornot[YESMK].ob_state = NORMAL;
  575.   mkornot[NOTMK].ob_state = NORMAL;
  576.   domark = execform(mkornot);
  577.  
  578.   /*
  579.    * One last chance to bail out.
  580.    */
  581.   *seldev = 'A';
  582.   if (dev > 15)    { /* it is a IDE-AT drive */
  583.       seldev = seldv;
  584.   } else if (dev > 7)    { /* it is a SCSI drive */
  585.           *seldev = 'S';
  586.   }
  587.   *(seldev + 10) = br + '0';
  588.   (fmtfnl[FUNIT].ob_spec)->te_ptext = seldev;
  589.   fmtfnl[FMTYES].ob_state = NORMAL;
  590.   fmtfnl[FMTNO].ob_state = NORMAL;
  591.   if (execform(fmtfnl) != FMTYES) return BAILOUT;
  592.  
  593.   /* For REAL !! */  
  594.   dsplymsg(fmtmsg);
  595.  
  596.   bsl = 0L;
  597.   
  598.   if ((dev > 15) && (!(athead*atcyl*atspt)))    {
  599.       formaterr(dev);
  600.     ret = ERROR;
  601.     goto formend;
  602.   }
  603.   /* Get size of Bad Sector List */
  604.   if ((bslsiz = gbslsiz(dev)) > 0L) {
  605.       /* Allocate memory for existing BSL */
  606.       if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  607.           ret = err(nomemory);
  608.           goto formend;
  609.       }
  610.       
  611.       /* Read in BSL */
  612.       if ((ret = rdbsl(dev)) != OK) {
  613.           /* Create a new BSL if current one is unusable */
  614.           if (creabsl(dev, NEW, 0L) != OK) {
  615.               ret = ERROR;
  616.               goto formend;
  617.           }
  618.       } else {
  619.             /* Remove USER BSL */
  620.             if (creabsl(dev, EXPAND, nument(VENDOR)) != OK) {
  621.                 ret = ERROR;
  622.                 goto formend;
  623.             }
  624.       }
  625.   } else if (bslsiz == 0L || bslsiz == ERROR) {    /* no bsl or read error */
  626.       if (creabsl(dev, NEW, 0L) != OK) {
  627.           ret = ERROR;
  628.           goto formend;
  629.       }
  630.   } else {    /* bslsiz == MDMERR; medium changed error */
  631.       ret = ERROR;
  632.       goto formend;
  633.   }
  634.   
  635.   /*
  636.    * In supervisor mode
  637.    * set disk format parameters
  638.    * and format the disk.
  639.    */
  640.   ostack = Super(NULL);
  641.   delay();
  642.   if (dev > 15)        { /* do the IDE-AT format */
  643.      if ((ret = fmtunt(dev)) != OK)    {
  644.       delay();
  645.         Super(ostack);
  646.       ret = errcode(dev);
  647.       if (tsterr(ret) != OK)
  648.           formaterr(dev);
  649.       ret = ERROR;
  650.     } else {
  651.         /* Apr-7-93 jye: This is a farmware bug, so have to recall identify()*/
  652.         /*             to update the head, cylinder, and spt                      */
  653.         if (identify(16, bs) == OK)    {
  654.             delay();
  655.             gparmfc(&atcyl, &athead, &atspt, bs); 
  656.         } else {
  657.             ret = ERROR;
  658.             goto formend;
  659.         }
  660.         if (dev == 16)    {/* it is a master IDE-AT */
  661.             hdsiz = athead*atcyl*atspt; 
  662.         } 
  663.           disksiz = hdsiz;
  664.         delay();
  665.           Super(ostack);
  666.     }
  667.     goto formend;
  668.   } 
  669.   set = typedev & (mask << dev);
  670.   scsidrv = typedrv & (mask << dev);
  671.   bsiz = ((set) || (scsidrv)) ? (16) : (22);
  672.   if (!noinfo)    {            /* there are info in the wincap */
  673.     if ((set) || (scsidrv))    {
  674.           v = mdsense(dev, 4, 0, 32, sendata);
  675.           delay();                    /* kludge delay */
  676.           sqms(dev, sendata);
  677.     } else {
  678.           if (modesel) {
  679.               v = ms(dev, &hinfo);    /* Yes, do noprmal mode set */
  680.         }
  681.     }
  682.       /* Find formatted capacity of drive */
  683.       hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt;
  684.   }    else if (dev < 8)    {        /* No, do special mode set */
  685.     for (i = 0; i < 32; i++)
  686.         sendata[i] = 0;
  687.     if ((set) || (scsidrv))    {
  688.           if (mdsense(dev, 0, 0, bsiz, sendata) == OK)        {
  689.             if (hdsiz = get3bytes(sendata+5))    {
  690.                   delay();                    /* kludge delay */
  691.                 sqms(dev, sendata);
  692.                 v = OK;
  693.                 goto kkk;
  694.             }
  695.         }
  696.   redopg:
  697.         for (i = 0; i < 32; i++)
  698.             sendata[i] = 0;
  699.           v = mdsense(dev, page, 0, 32, sendata);
  700.           for (i = 0; i < 32; i++) /* the lenght of sendata */
  701.               if (sendata[i])
  702.                 break;
  703.           if ((i == 32) && (page == 4))    { /* no informations returned */
  704.             page = 3;
  705.             goto redopg;
  706.           } else if (i == 32)    {
  707.             ret = 111;
  708.               delay();                    /* kludge delay */
  709.               Super(ostack);
  710.             goto formend;
  711.         }
  712.         if (page == 4)    {
  713.             if (!(hdsiz = get3bytes(sendata+5)))    {
  714.                 page = 3;
  715.                 /*
  716.                 cyl = get3bytes(sendata+14);
  717.                 head = *(sendata+17);
  718.                 if ((!cyl) || (!head))    {
  719.                     ret = 111;
  720.                       delay();        
  721.                       Super(ostack);
  722.                     goto formend;
  723.                 }
  724.                 */
  725.                 sqms(dev, sendata);
  726.                 goto redopg;
  727.             }
  728.             sqms(dev, sendata);
  729.             goto kkk;
  730.         } 
  731.         if (!(hdsiz = get3bytes(sendata+5)))    {
  732.             /*
  733.             spt = getword(sendata+22);
  734.             hdsiz = cyl*head*spt;
  735.             */
  736.             if (!hdsiz)        {
  737.                 ret = 111;
  738.                   delay();                    /* kludge delay */
  739.                   Super(ostack);
  740.                 goto formend;
  741.             }
  742.         }
  743.         goto kkk;
  744.     } else {    /* it is the acsi drivers */
  745.           hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt;
  746.           delay();                    /* kludge delay */
  747.           v = ms(dev, &hinfo);    /* Yes, do noprmal mode set */
  748.     }
  749.   }    else {
  750.         if ((v = readcap(dev, 0, (long)0, buf)) == OK)    {
  751.             if ((hdsiz = get4bytes(buf)))    {
  752.                 hdsiz += 1;
  753.                 ret = OK;
  754.                 goto kkk;
  755.             } 
  756.         } 
  757.           delay();                    /* kludge delay */
  758.         for (i = 0; i < 32; i++)
  759.             sendata[i] = 0;
  760.           if ((v=mdsense(dev, 0, 0, bsiz, sendata)) == OK)        {
  761.             if (hdsiz = get3bytes(sendata+5))    {
  762.                 ret = OK;
  763.                 goto kkk;
  764.             }
  765.         }
  766.         for (i = 0; i < 32; i++)
  767.             sendata[i] = 0;
  768.           delay();                    /* kludge delay */
  769.           if ((v=mdsense(dev, 4, 0, 32, sendata)) == OK)        {
  770.             if (hdsiz = get3bytes(sendata+5))    {
  771.                 ret = OK;
  772.                 goto kkk;
  773.             }
  774.         }
  775.         for (i = 0; i < 32; i++)
  776.             sendata[i] = 0;
  777.           delay();                    /* kludge delay */
  778.           if ((v=mdsense(dev, 3, 0, 32, sendata)) == OK)        {
  779.             if (hdsiz = get3bytes(sendata+5))    {
  780.                 ret = OK;
  781.                 goto kkk;
  782.             }
  783.         }
  784.         ret = 111;
  785.           delay();                    /* kludge delay */
  786.           Super(ostack);
  787.         goto formend;
  788.   }
  789. kkk:
  790.   disksiz = hdsiz;
  791.   delay();                    /* kludge delay */
  792.   if (v == OK)    {
  793.       if (floptical)    { /* to unlock the write protection in floptical drive*/
  794.           mdsense(dev, 0x2e, 0, 32, sendata);
  795.           delay();                    /* kludge delay */
  796.     }
  797.       v = format(dev, (UWORD)hinfo.hi_in);  /*format*/
  798.   }
  799. lll:
  800.   delay();                    /* kludge delay */
  801.   Super(ostack);
  802.   
  803.   if (v != 0)  {
  804.       ret = errcode(dev);
  805.       if (tsterr(ret) != OK)
  806.           formaterr(dev);
  807.       ret = ERROR;
  808.       goto formend;
  809.   }
  810.   
  811.   ret = OK;
  812.   rebootp = 1;
  813. formend:
  814.   erasemsg();    /* Erase formatting box */
  815.   if (ret == 111)        /* HDX may not support this drive */
  816.           ret = err(needinfo);
  817.   if (ret < 0) {
  818.       if (bsl > 0) free(bsl);
  819.       return ERROR;
  820.   }
  821.   
  822.   /*------------------------------------------*
  823.    * Markbad the device destructively.          *
  824.    * Bad Sectors found are added to the BSL.  *
  825.    * Write BSL to device.              *
  826.    *------------------------------------------*/
  827.   if (domark == YESMK)    { /* need to do the markbad */
  828.       if ((nbad = dsmarkbad(dev, hdsiz, 1, pattern)) < 0) {
  829.           free(bsl);
  830.           return ERROR;
  831.       }
  832.   }
  833.   if (wrbsl(dev) != OK) {
  834.       free(bsl);
  835.       return ERROR;
  836.   }
  837.   free(bsl);
  838.  
  839.     
  840.   /*
  841.    * Install boot-stopper in sector image;
  842.    * write root sector to device.
  843.    * 6-13-88  Setting of soft format parameters in root sector sets
  844.    *        the hard disk size only.
  845.    */
  846.   fillbuf(bs, 512L, 0L);    /* create new root sector */
  847.   sbslparm(bs);            /* set BSL parameters */
  848.   if (modesel)    {
  849.       sfmtparm(bs, &hinfo);
  850.   } else {
  851.       sdisksiz(bs, disksiz);
  852.   }
  853.   for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  854.     *d++ = *s++;
  855.   Protobt(bs, -1L, -1, 1);    /* make root sector executable */
  856.   
  857.   if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  858.       if (tsterr(ret) != OK)
  859.           err(rootwrit);
  860.       return ERROR;
  861.   }
  862.  
  863.   /*
  864.    * Make a copy of the default partition name.
  865.    * Figure out the partition scheme id.
  866.    */
  867.   if (!noinfo)    {
  868.       s = wgetstr("pt");
  869.       strcpy(pnam, s);
  870.   }
  871.   /* ??
  872.   figprid(disksiz, pr_id);
  873.   */
  874.   dodipart(dev, pnam, disksiz);
  875.   return OK;
  876. }
  877.  
  878.  
  879.  
  880. /*
  881.  * Handle [PARTITION] item;
  882.  * if `xdev' is -1, throw up dialog boxes;
  883.  * if `xdev' >= 0, just partition the dev,
  884.  * using `pnam' as the partition type, 
  885.  * and `pr_id' to search for the type.
  886.  *
  887.  */
  888. dodipart(xdev, pnam, hsize)
  889. int xdev;
  890. char *pnam;
  891. long hsize;
  892. {
  893.     int dev, i, ret =OK, fine;
  894.     int choice;
  895.     char *seldev = "ACSI unit 0";
  896.       char *seldv =  "IDE  unit 0";
  897.     char *s;
  898.     char bs[512];
  899.     PART *pinfo;
  900.     int tem1, tem2;
  901.     long disksiz;
  902.     int mask = 0x0001;
  903.  
  904.     if (xdev < 0) {
  905.     /*
  906.      * Throw up warning saying that partition is dangerous;
  907.      * then get physical dev they want to clobber.
  908.      */
  909.     pwarning[PWARNCN].ob_state = NORMAL;
  910.     pwarning[PWARNOK].ob_state = NORMAL;
  911.     if (execform(pwarning) != PWARNOK) return BAILOUT;
  912.     tformat = FALSE;
  913.     if ((dev = gphysdev()) < 0) {
  914.         return BAILOUT;
  915.     }
  916.     /*
  917.      * Let the user edit/pick partitions.
  918.      */
  919.     fine = 0;
  920.     while (!fine) {
  921.         if (sfigpart(bs, dev, (PART *)&pinfo) != OK)    {
  922.             if (pinfo > 0)    Mfree(pinfo);
  923.             return BAILOUT;
  924.         }
  925.         if ((ret = chkpart(dev, pinfo)) != OK) {
  926.             if (ret < 0)    {    /* size too big */
  927.                 err(nexsmem);
  928.             } else {    /* some other errors  */
  929.                 if (pinfo > 0)    Mfree(pinfo);
  930.                 return BAILOUT;
  931.             }
  932.         } else {
  933.             fine = 1;
  934.         }
  935.     }
  936.  
  937.       fine = dev;            /* default for the acsi unit */
  938.     *seldev = 'A';
  939.       if (dev > 15)    { /* it is a IDE-AT drive */
  940.         fine = dev - 16;
  941.         seldev = seldv;
  942.     } else if (dev > 7)     {    /* minus 8 for the scsi drive number */
  943.         fine = dev - 8;
  944.         *seldev = 'S';
  945.     }
  946.     *(seldev + 10) = fine + '0';
  947.  
  948.     /* Last chance to bail out */
  949.     (partfnl[PUNIT].ob_spec)->te_ptext = seldev;
  950.     partfnl[PARTYES].ob_state = NORMAL;
  951.     partfnl[PARTNO].ob_state = NORMAL;
  952.     if (execform(partfnl) != PARTYES)    {
  953.         if (pinfo > 0)    Mfree(pinfo);
  954.         return BAILOUT;
  955.     }
  956.  
  957.     } else {
  958.         /* ??
  959.         if ((!noinfo) && (!ttscsi) && (wgetent(pnam, pr_id) != OK)) {
  960.             nopart[NOSCHPOK].ob_state = NORMAL;
  961.             (nopart[NOSCHPR].ob_spec)->te_ptext = pnam;
  962.             execform(nopart);
  963.             return ERROR;
  964.         }
  965.         */
  966.         npart = 4;
  967.         ext = NO_EXT;    /* set the extended partition flag to not exists */
  968.         dev = xdev;
  969.         if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0)    {
  970.             err(nomemory);
  971.             if (pinfo > 0)    Mfree(pinfo);
  972.             return ERROR;
  973.         }
  974.         inipart(pinfo, npart);
  975.         npart = 0;
  976.         setpart(pinfo, pnam, hsize);
  977.         /* ??
  978.         if (ttscsi)        {     SCSI bus drive 
  979.             setpart(pinfo, hsize);
  980.         } else {             regular drvie 
  981.             for (i = 0; i < 4; ++i)
  982.                 fillpart(i, &pinfo[i]);
  983.         }
  984.         */
  985.     }
  986.  
  987.     /* For REAL!! */
  988.     dsplymsg(partmsg);
  989.     
  990.     bsl = 0L;
  991.     
  992.     /* Get size of BSL */
  993.     if ((bslsiz = gbslsiz(dev)) > 0L) {
  994.         /* Allocate memory for existing BSL */
  995.         if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  996.             ret = err(nomemory);
  997.             goto partend;
  998.         }
  999.             
  1000.         /* Read in BSL */
  1001.         if ((ret = rdbsl(dev)) != OK) {
  1002.             if (ret == INVALID)
  1003.                 err(cruptbsl);
  1004.             ret = ERROR;
  1005.             goto partend;
  1006.         }
  1007.     } else if (bslsiz == 0) {
  1008.         ret = err(oldfmt);
  1009.         goto partend;
  1010.     } else if (bslsiz == ERROR) {
  1011.         ret = err(rootread);
  1012.         goto partend;
  1013.     } else {
  1014.         ret = ERROR;
  1015.         goto partend;
  1016.     }
  1017.  
  1018.     
  1019.     /* Lay out partition headers */
  1020.     if (spheader(dev, &pinfo[0]) != OK) {
  1021.         ret = ERROR;
  1022.         goto partend;
  1023.     }
  1024.     
  1025.     if (wrbsl(dev) != OK) {        /* write BSL */
  1026.         ret = ERROR;
  1027.         goto partend;
  1028.     }
  1029.  
  1030.     /* check and change the structure's id after 'spheader()' */
  1031.     changeid(pinfo);
  1032.  
  1033.     /* Shove partition parms into root sector */
  1034.     if ((ret = getroot(dev, bs, (SECTOR)0)) != 0)    {
  1035.         if (tsterr(ret) != OK)
  1036.             err(rootread);
  1037.         ret = ERROR;
  1038.         goto partend;
  1039.     }
  1040.  
  1041.     if ((ret = stlayroot(bs, dev, pinfo)) != OK)    {
  1042.         goto partend;
  1043.     }
  1044.     tem1 = npart;            /* save the number of partitions */
  1045.     tem2 = ext;                /* save the index of extended partition */
  1046.     if (rescan(1,2)) {        /* has to be here because map changed    */
  1047.         ret = ERROR;        /* after partitions are moved around,    */
  1048.         goto partend;        /* report medium change error.        */
  1049.     }
  1050.     npart = tem1;
  1051.     ext = tem2;
  1052.     /* Partition the device with parameters given in pinfo */
  1053.     if (stlaybs(dev, &pinfo[0]) != OK)
  1054.         ret = ERROR;
  1055.     else
  1056.         ret = OK;
  1057.         
  1058.     rebootp = 1;
  1059.     /*  add on Jul 2, 90 for removable drive
  1060.     if ((typedev & (mask << dev)))             it is a removable drive 
  1061.         if (npart <= prevnpart)                 if less or equal than prevous 
  1062.             rebootp = 0;                      partition, don't reboot 
  1063.     change and add over on Jul 2, 90 for the removable drive on Oct 1, 90
  1064.     if ((typedev & (mask << dev)))    {         it is a removable drive 
  1065.         for (i = 0; i < 10; i++)     {
  1066.             if (!mediach(dev))            
  1067.                 break;
  1068.             if (i == 10)
  1069.                 rebootp = 1;
  1070.             else
  1071.                 rebootp = 0;
  1072.         }
  1073.     }
  1074.     */
  1075.     pnf = 1;        /* set the flag to just doing the partition */
  1076. partend:
  1077.     if (bsl > 0) free(bsl);
  1078.     inipart(pinfo, npart);
  1079.     if (pinfo > 0)    Mfree(pinfo);
  1080.     erasemsg();
  1081.     return (ret);
  1082. }
  1083.  
  1084.  
  1085. /*
  1086.  * get root sector informations and write them into that sector 
  1087.  */
  1088.  
  1089. stlayroot(bs, dev, part)
  1090. char *bs;
  1091. int dev;
  1092. PART *part;
  1093. {
  1094.     int i;
  1095.     UWORD sum = 0x1234;
  1096.     long cnt, disksiz, prvst;
  1097.     char *d, *s;
  1098.     extern char bootstop;
  1099.     extern char bootend;
  1100.  
  1101.     /* do the prime partition */
  1102.     spart(bs, part, 0, &prvst);    /* set ST partition parameters */
  1103.     /*
  1104.       sfmtparm(bs, &hinfo);
  1105.       for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  1106.         *d++ = *s++;
  1107.     */
  1108.     sbslparm(bs);                /* set bsl parameters */
  1109.     Protobt(bs, -1L, -1, 1);        /* make root sector executable */
  1110.     if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  1111.         if (tsterr(ret) != OK)
  1112.             err(rootwrit);
  1113.         return(ERROR);
  1114.     }
  1115.     if (ext == NO_EXT)    return OK;        /* no extended partition */
  1116.     /* do the extended partitions */
  1117.     extsiz = part[ext].p_siz;
  1118.     for (i = 4; i < npart; i++)    {
  1119.         if (!(part[i].p_flg & P_EXISTS))    {     /* skip if not exists */
  1120.             return OK;
  1121.         }
  1122.         spart(bs, part, i, &prvst);    /* set IBM partition parameters */
  1123.         if ((ret = putroot(dev, bs, part[i].p_st)) != OK) {
  1124.             if (tsterr(ret) != OK)
  1125.                 err(rootwrit);
  1126.             return(ERROR);
  1127.         }
  1128.     }
  1129.     return OK;
  1130. }
  1131.  
  1132.  
  1133.  
  1134.  
  1135. /*
  1136.  * Put information into the root structure
  1137.  */
  1138.  
  1139. spart(image, pinfo, pnm, prvst)
  1140.  
  1141. char *image;            /* root sector buffer */
  1142. register PART *pinfo;    /* partition information */
  1143. int pnm;                /* partition number */
  1144. long *prvst;            /* The previous partition start sector */
  1145.  
  1146. {
  1147.     PART *rpart;
  1148.     long numcyl;
  1149.     int i, j;
  1150.  
  1151.     if (pnm)     {
  1152.         fillbuf(image, 512L, 0L);
  1153.     }
  1154.     rpart = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_p[0];
  1155.     if (pnm < 4)    {
  1156.         for (i = 0; i < NPARTS; i++, rpart++)    {
  1157.             if (pinfo->p_flg & P_EXISTS)    {
  1158.                 rpart->p_flg = P_EXISTS;
  1159.                 for (j = 0; j < 3; j++)
  1160.                     rpart->p_id[j] = pinfo->p_id[j];
  1161.                 rpart->p_st = pinfo->p_st;
  1162.                 rpart->p_siz = pinfo->p_siz;
  1163.             } else {
  1164.                 rpart->p_flg = 0;
  1165.                 for (j = 0; j < 3; j++)
  1166.                     rpart->p_id[j] = 0;
  1167.                 rpart->p_st = 0L;
  1168.                 rpart->p_siz = 0L;
  1169.             }
  1170.             pinfo++;
  1171.         }
  1172.  
  1173.     } else {    /* pnm => 4 */
  1174.         rpart->p_flg = pinfo[pnm].p_flg;
  1175.         for (j = 0; j < 3; j++)
  1176.             rpart->p_id[j] = pinfo[pnm].p_id[j];
  1177.         rpart->p_st = ROOTSECT;
  1178.         rpart->p_siz = pinfo[pnm].p_siz - ROOTSECT;
  1179.         rpart++;
  1180.         if (((pnm + 1) != npart) && (pinfo[pnm+1].p_flg & P_EXISTS)) { 
  1181.             /* need extened partition */
  1182.             rpart->p_flg = P_EXISTS;
  1183.             rpart->p_id[0] = 'X';
  1184.             rpart->p_id[1] = 'G';
  1185.             rpart->p_id[2] = 'M';
  1186.             rpart->p_siz = pinfo[pnm+1].p_siz;
  1187.             rpart->p_st = (pnm == 4) ? (pinfo[4].p_siz) :
  1188.                                     (pinfo[pnm].p_siz + *prvst);
  1189.             *prvst = rpart->p_st;
  1190.         }
  1191.  
  1192.     }
  1193. }
  1194.  
  1195.  
  1196.  
  1197. /*
  1198.  * Setup partitions on the disk;
  1199.  * write boot sectors and zero FATs and root directories.
  1200.  *
  1201.  */
  1202. stlaybs(physdev, pinfo)
  1203. int physdev;
  1204. register PART *pinfo;
  1205. {
  1206.     int i, ldev, ret;
  1207.     int kindfat;
  1208.     SECTOR data, nsect;
  1209.     char *devno="X";
  1210.     long ndirs;
  1211.     UWORD fatsiz;
  1212.     BOOT *bs;
  1213.     long serialno;
  1214.     extern long longrandom();
  1215.     extern long cell();
  1216.     char *buf, *buf1;
  1217.     long size, remsect;
  1218.     long datsect;
  1219.     long datclst; 
  1220.     long fatclst;
  1221.     long entsect;
  1222.  
  1223.     if ((bslsiz = gbslsiz(physdev)) < 0L) {
  1224.         if (bslsiz == ERROR)
  1225.             err(rootread);
  1226.         return ERROR;
  1227.     }
  1228.     /* SCAN_BS: pinfo is for scan() and laybs() use */
  1229.     if (ext != NO_EXT)    sortpart(pinfo, SCAN_BS);    
  1230.  
  1231.     for (i = 0; i < npart; ++i, ++pinfo) {
  1232.         
  1233.         /* don't care if partition does not exist */
  1234.         if (!(pinfo->p_flg & P_EXISTS)) {
  1235.             return OK;
  1236.         }
  1237.  
  1238.  
  1239.     /*
  1240.      * Compute boot sector parameters.
  1241.      */
  1242.         if (pinfo->p_siz > disksiz) {        /* partition >? disk size */
  1243.             *devno = i + '0';
  1244.             (part2big[BGPART].ob_spec)->te_ptext = devno;
  1245.             part2big[BGPARTOK].ob_state = NORMAL;
  1246.             execform(part2big);
  1247.             return ERROR;
  1248.         }
  1249.  
  1250.     /* estimat the bps */
  1251.     /* MAXSECT = 16MB - 8 */
  1252.     bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT);
  1253.  
  1254.     /* the real bps */
  1255.     bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  1256.     ratio = bps / BPS;
  1257.     nsect = pinfo->p_siz / ratio;
  1258.  
  1259.     size = (long)BPS * ratio;
  1260.     if ((buf = (char *)Malloc(size)) <= 0)    {
  1261.         err(nomemory);
  1262.         if (buf > 0) Mfree((long)buf);
  1263.         return ERROR;
  1264.     }
  1265.  
  1266.     /*
  1267.      * Install entries in boot sector image;
  1268.      * force sector checksum to zero (non-executable);
  1269.      * write boot sector to media.
  1270.      *
  1271.       *    512 bytes/sector
  1272.      *    2 or 4 sectors/cluster (partition > 16Mb has 4 spc)
  1273.      *    1 reserved sector (for boot)
  1274.      *    2 FATs
  1275.      *    ... dir slots
  1276.      *    ... # sectors
  1277.      *    F8 means media is a hard disk
  1278.      *    ... FAT size
  1279.      *
  1280.      */
  1281.      
  1282.     /* Make a clean boot sector */
  1283.     fillbuf(buf, bps, 0L);
  1284.     bs = (BOOT *)buf;
  1285.         
  1286.  
  1287.     /* bytes per sector */
  1288.     iw((UWORD *)&bs->b_bps[0], (UWORD)bps);
  1289.     
  1290.     /* sectors per cluster */
  1291.     bs->b_spc = SPC;
  1292.         
  1293.     /* number of reserved sectors */
  1294.     iw((UWORD *)&bs->b_res[0], (UWORD)1);
  1295.     
  1296.     /* number of FATs */
  1297.     bs->b_nfats = 2;
  1298.     
  1299.  
  1300.     /*
  1301.      * Compute root directory size
  1302.      * 256 entries, plus fudge on devs > 10Mb
  1303.      */
  1304.     if (pinfo->p_siz < 0x5000L) ndirs = NUMEN;
  1305.     else ndirs = nsect / 80;    /* 1 dir entry per 80 sectors */
  1306.     /* round to nearest sector */
  1307.     ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1);    
  1308.     iw((UWORD *)&bs->b_ndirs[0], (UWORD)ndirs);
  1309.     
  1310.     /* number of sectors on media (partition) */
  1311.     iw((UWORD *)&bs->b_nsects[0], (UWORD)nsect);
  1312.  
  1313.     /* media descriptor */
  1314.     bs->b_media = 0xf8;
  1315.  
  1316.     /*--------------------------------------------------------------*
  1317.      * Compute FAT size                        *
  1318.      *                                *
  1319.      * Num entries to map the entire partition            *
  1320.      *    = partition's size in clusters                *
  1321.      *    = partition's size in sectors / spc            *
  1322.      *                                *
  1323.      * Num entries in FAT                        *
  1324.      *    = Num entries to map partition + reserved entries    *
  1325.      *    = (partition's size in sectors / spc) + 2        *
  1326.      *                                *
  1327.      * Num sectors FAT occupies                    *
  1328.      *    = Num entries in FAT / Num entries of FAT per sector    *
  1329.      *    = Num entries in FAT / (bps / 2)    <16-bit FAT>    *
  1330.      *    = ((partition's size in sectors / spc) + 2) / (bps/2) + 1    *
  1331.      *                        <+1 to round up>    *
  1332.      *--------------------------------------------------------------*/
  1333.     fatsiz = ((((nsect / bs->b_spc) + 2) * 2) / bps) + 1;/*bps ?? 512 or 1024*/
  1334.     iw((UWORD *)&bs->b_spf[0], (UWORD)fatsiz);
  1335.  
  1336.     /* write the serial number to the bs */ 
  1337.     Protobt(bs, 0x01000000, -1, -1);
  1338.  
  1339.     /*
  1340.      * Write partition's boot sector
  1341.      */
  1342.     forcesum((UWORD *)buf, (UWORD)0);    /* force image checksum */
  1343.     if ((ret = wrsects(physdev,(UWORD)ratio,buf,(SECTOR)pinfo->p_st))!= OK) {
  1344.         if (tsterr(ret) != OK)
  1345.             err(bootwrit);
  1346.         return ERROR;
  1347.     }
  1348.  
  1349.     /*
  1350.      * Zero the fat tables directory entry 
  1351.      */
  1352.     if ((ret = zerosect(physdev, (SECTOR)(pinfo->p_st+ratio),
  1353.              ((UWORD)((fatsiz*2 + ndirs*BPDIR/bps) * ratio)))) != OK) {
  1354.         if (tsterr(ret) != OK)
  1355.             err(hdrwrite);
  1356.         return ERROR;
  1357.     }
  1358.     /* Apr-23-93 jye: To fixed the same bug in the Gemdos.
  1359.      * Num entries in FAT                        *
  1360.      *    = Num entries to map partition + reserved entries    *
  1361.      *    = (partition's size in sectors / spc) + 2        *
  1362.      *                                *
  1363.      * Num sectors FAT occupies                    *
  1364.      *    = Num entries in FAT / Num entries of FAT per sector    *
  1365.      *    = Num entries in FAT / (bps / 2)    <16-bit FAT>    *
  1366.      * 
  1367.      * Num entries in the last sector of FAT
  1368.      * = (nsect/spc + 2) % (bps/2)
  1369.      * 
  1370.      * The pointer(or counter in byte)after the last entries in the FAT
  1371.      * = ((nsect/spc + 2) % (bps/2))*ratio*2 (16bit fat is 2 bytes)
  1372.      */
  1373.     /* # of sectors in datas:  
  1374.      *                 datsect   = nsect - boot - 2*fatsiz - size of dir 
  1375.      *                           = nsect-boot-2*fatsiz-(ndirs*32)/bps
  1376.      * # of clusters in datas: 
  1377.      *                datclst      = # of sectors in datas / SPC 
  1378.      * # of clusters(entries) in Fat: 
  1379.      *                fatclst   = fatsiz * (bps/2)
  1380.      * # of sectors need in fat talbe for datclst:
  1381.      *                entsect   = datclst / (bps/2)
  1382.      * # of sectors need to remodify to 0xffff:
  1383.      *                remsect   = fatsiz - entsect
  1384.      */
  1385.  
  1386.     datsect = nsect - 1 - 2*fatsiz - (ndirs*32)/bps;
  1387.     datclst = datsect / SPC;
  1388.     fatclst = fatsiz * (bps/2);
  1389.     entsect = datclst / (bps/2);
  1390.     remsect = (fatsiz - entsect)*size;
  1391.  
  1392.  
  1393.     /* # of sectors need to remodify to 0xffff */
  1394.     if ((buf1 = (char *)Malloc(remsect)) <= 0)    {
  1395.         err(nomemory);
  1396.         if (buf > 0) Mfree((long)buf);
  1397.         if (buf1 > 0) Mfree((long)buf1);
  1398.         return ERROR;
  1399.     }
  1400.  
  1401.     /* 
  1402.      * Apr-23-93 jye: To fixed the write over to next partitiona in the Gemdos  
  1403.      *                  , here just set those entries in Fat table, which don't
  1404.      *                  correspond to the availble date sectors in the partition.
  1405.      *                  The pointers should be:
  1406.      *                      p_st+(boot+datclst/(bps/2))*ratio and 
  1407.      *                    p_st+(boot+fatsiz+datclst/(bps/2))*ratio 
  1408.      */
  1409.     if ((ret = rdsects(physdev, (UWORD)(remsect/BPS), buf1, 
  1410.                      (SECTOR)pinfo->p_st+(1+datclst/(bps/2))*ratio)) != OK) {
  1411.         if (tsterr(ret) != OK)
  1412.             err(bootwrit);
  1413.         return ERROR;
  1414.     }
  1415.     /* fill the last sectors of FAT start at last entry with the 0xffff */
  1416.     /* +2 is for two reserved entries in the fat table */
  1417.     fillfat(buf1, ((datclst%(bps/2))+2)*2, remsect, 0xffff);
  1418.     if ((ret = wrsects(physdev,(UWORD)(remsect/BPS),buf1,
  1419.                      (SECTOR)pinfo->p_st+(1+datclst/(bps/2))*ratio) != OK) ||
  1420.         (ret = wrsects(physdev,(UWORD)(remsect/BPS),buf1,
  1421.              (SECTOR)pinfo->p_st+(1+fatsiz+datclst/(bps/2))*ratio) != OK)) {
  1422.         if (tsterr(ret) != OK)
  1423.             err(bootwrit);
  1424.         return ERROR;
  1425.     }
  1426.     /* Apr-23-93 jye: Add above codes to fix the Gemdos over write next
  1427.      *                   partition.
  1428.      */
  1429.  
  1430.              
  1431.     /*
  1432.      * Make first 2 entries in FATs more IBM-like.
  1433.      */
  1434.     if ((ret = rdsects(physdev,(UWORD)ratio,buf,
  1435.                         (SECTOR)(pinfo->p_st+ratio)))!= 0){
  1436.         if (tsterr(ret) != OK)
  1437.             err(fatread);
  1438.         return ERROR;
  1439.     }
  1440.     *(UWORD *)&buf[0] = 0xf8ff;
  1441.     *(UWORD *)&buf[2] = 0xffff;
  1442.     if ((ret = wrsects(physdev,(UWORD)ratio,
  1443.                         buf,(SECTOR)(pinfo->p_st+ratio)))!= 0 ||
  1444.         (ret = wrsects(physdev,(UWORD)ratio,buf,
  1445.                         (SECTOR)(pinfo->p_st+ratio+fatsiz*ratio)))
  1446.         != 0) {
  1447.         if (tsterr(ret) != OK)
  1448.             err(fatwrite);
  1449.         return ERROR;
  1450.     }
  1451.  
  1452.     /*
  1453.      * Mark bad sectors recorded in the BSL into the FATs.
  1454.      * Calculating parameters:
  1455.      *    ldev - from physdev and i.
  1456.      *    fat0 - always equals 1.
  1457.      *    fatsiz - calculated above.
  1458.      *    data - starts after the boot sector, 2 FATs and rootdir.
  1459.      */
  1460.  
  1461.         if (bslsiz > 0) {
  1462.             if ((ldev = phys2log(physdev, i)) == ERROR)
  1463.                 return parterr(physdev);
  1464.             data = (SECTOR)1 + (SECTOR)(fatsiz*2) + (SECTOR)(ndirs*BPDIR/bps);
  1465.             bsl2fat(ldev, (SECTOR)ratio, (UWORD)(fatsiz*ratio), 
  1466.                                                 data*ratio, MEDIA);
  1467.         }
  1468.         if (buf > 0) Mfree((long)buf);
  1469.         if (buf1 > 0) Mfree((long)buf1);
  1470.     }
  1471.     return OK;
  1472. }
  1473.  
  1474.  
  1475.  
  1476.  
  1477. /*
  1478.  * Handle [ZERO] item.
  1479.  *
  1480.  */
  1481. dodizero()
  1482. {
  1483.     int ldev, ret;
  1484.     char *seldev = "X";
  1485.     int i; 
  1486.  
  1487.     zwarning[ZWOK].ob_state = NORMAL;
  1488.     zwarning[ZWCN].ob_state = NORMAL;
  1489.     if (execform(zwarning) != ZWOK)
  1490.     return BAILOUT;
  1491.     if (showmany)    err(manyldev);
  1492.  
  1493.     if ((ldev = glogdev()) < 0) return BAILOUT;
  1494.  
  1495.     /* Find out if logical device has assumed parameters */
  1496.     if (chkparm(ldev) != OK) {
  1497.         wronparm[WRONOK].ob_state = NORMAL;
  1498.     execform(wronparm);
  1499.     return ERROR;
  1500.     }
  1501.         
  1502.     *seldev = ldev;
  1503.     (zerofnl[ZDRV].ob_spec)->te_ptext = seldev;
  1504.     strcat((zerofnl[ZDRV].ob_spec)->te_ptext, ":");
  1505.     zerofnl[ZYES].ob_state = NORMAL;
  1506.     zerofnl[ZNO].ob_state = NORMAL;
  1507.     if (execform(zerofnl) != ZYES)  return BAILOUT;
  1508.  
  1509.     dsplymsg(zeromsg);
  1510.     if (zero(ldev) == OK) {
  1511.     if (!rebootp) {
  1512.         for (i = 0; i < 10; i++) {
  1513.         if (!mediach(ldev-'A')) break;
  1514.         }
  1515.         if (i == 10) {
  1516.             rebootp = 1;
  1517.         err(mdach);
  1518.             }
  1519.     }
  1520.     }
  1521.     erasemsg();
  1522. }
  1523.  
  1524.  
  1525. /*
  1526.  * Handle [MARKBAD] item.
  1527.  *
  1528.  */
  1529. dodimark()
  1530. {
  1531.     int ldev, ret;
  1532.     int i;
  1533.  
  1534.     mwarning[MWARNOK].ob_state = NORMAL;
  1535.     mwarning[MWARNCN].ob_state = NORMAL;
  1536.     if (execform(mwarning) == MWARNCN)
  1537.         return BAILOUT;
  1538.     if (showmany)    err(manyldev);
  1539.  
  1540.     if ((ldev = glogdev()) < 0)
  1541.         return BAILOUT;
  1542.         
  1543.     /* Find out if logical device has assumed parameters */
  1544.     if (chkparm(ldev) != OK) {
  1545.         wronparm[WRONOK].ob_state = NORMAL;
  1546.     execform(wronparm);
  1547.     return ERROR;
  1548.     }
  1549.          
  1550.     dsplymsg(lmrkmsg);
  1551.     if (markbad(ldev) != OK) {
  1552.         erasemsg();
  1553.     } else {
  1554.         if (!rebootp) {
  1555.         for (i = 0; i < 10; i++) {
  1556.         if (!mediach(ldev-'A')) break;
  1557.         }
  1558.         if (i == 10) {
  1559.             rebootp = 1;
  1560.         err(mdach);
  1561.             }
  1562.         }
  1563.     }
  1564. }
  1565.  
  1566.  
  1567. /*
  1568.  * Translate unit number to tree index.
  1569.  *
  1570.  */
  1571. static int physxlat[] = {
  1572.     UNIT0, UNIT1, UNIT2, UNIT3
  1573. };
  1574.  
  1575. static int physid[] = {
  1576.     DRVID0, DRVID1, DRVID2, DRVID3
  1577. };
  1578.  
  1579. #define ROLL1 1            /* move the bar one step */
  1580. #define ROLL4 4            /* move the bar four steps */
  1581.  
  1582. /*
  1583.  * Ship selected devices.
  1584.  */
  1585. dodiship()
  1586. {
  1587.   
  1588.     int xrun = 1;
  1589.     int index=0, i, ret;
  1590.  
  1591.     linkdev();            /* link all live devices into a list */
  1592.     /* set form for first display */
  1593.     physdial[PHYSOK].ob_state = NORMAL;
  1594.     physdial[PHYSCN].ob_state = NORMAL;
  1595.     physdial[SLBOX].ob_y = 0;
  1596.     if (ndevs <= 4)    {
  1597.         physdial[SLBOX].ob_height = physdial[SLTRK].ob_height;
  1598.     } else {
  1599.         physdial[SLBOX].ob_height = physdial[SLTRK].ob_height / (ndevs/4.0);
  1600.     }
  1601.     ok2draw = 0;
  1602.     drawdev(index);    /* draw the devices into the dialog box */
  1603.     ARROW_MOUSE;
  1604.     dsplymsg(physdial);
  1605.     ++ok2draw;
  1606.     while (xrun)     {
  1607.         switch (form_do(physdial, -1))     {
  1608.             case PHYSOK:xrun = 0;
  1609.                         break;
  1610.             case PHYSCN:xrun = 0;            /* return */
  1611.                         break;
  1612.             case SLTRK: if (ndevs > 5)    {
  1613.                             scrupdn(ROLL4, &index);
  1614.                         }
  1615.                         break;
  1616.             case SLUP:  if (index != 0)    {
  1617.                             scrupdn(ROLL1, &index);
  1618.                         }
  1619.                         break;
  1620.             case SLDN:  if ((index < 12) && (index+4 < ndevs))    {
  1621.                             scrupdn(ROLL1, &index);
  1622.                         }
  1623.                         break;
  1624.             case SLBOX: if (ndevs > 5)    {
  1625.                             slidebox(physdial, &index);
  1626.                         }
  1627.                         break;
  1628.           }
  1629.       }
  1630.  
  1631.   /*
  1632.    * Draw shrinking box and cleanup the screen;
  1633.    * return thing that caused our exit.
  1634.    */
  1635.     erasemsg();
  1636.  
  1637.     if (ret == PHYSCN)    {
  1638.         return BAILOUT;
  1639.     }
  1640.     /* search for the selected unit */
  1641.     for (i=0; i < 4; i++)    {
  1642.         if (physdial[physxlat[i]].ob_state & SELECTED)    {
  1643.               /* Throw up final shipping warning. */
  1644.               shipfnl[SFNLCN].ob_state = NORMAL;
  1645.               shipfnl[SFNLOK].ob_state = NORMAL;
  1646.               if (execform(shipfnl) != SFNLOK) return BAILOUT;
  1647.             ship(devid[index+i].dev);
  1648.               /* Put out final message about turning off hard disks */
  1649.               scommand[TRNOFFOK].ob_state = NORMAL;
  1650.               execform(scommand);
  1651.         }
  1652.     }
  1653.     return BAILOUT;
  1654. }
  1655.   
  1656.  
  1657. /*
  1658.  * Get physical device#,
  1659.  * return devno or -1.
  1660.  *
  1661.  */
  1662. gphysdev()
  1663.  
  1664. {
  1665.     int xrun = 1, tpdev=0;
  1666.     int index=0, i, ret;
  1667.  
  1668.     linkdev();            /* link all live devices into a list */
  1669.     if (tformat)    {    /* when format, enable all devices in dialog box */
  1670.         if ((spscsixst)    || (atexst)) { /* sparrow or notebook */
  1671.             ndevs = 9;
  1672.             tpdev = 8;
  1673.         } else if (ttscsi) {
  1674.             ndevs = 16;
  1675.         } else { /* if ((!ttscsi) && (!noacsi))     Mega ST */
  1676.             ndevs = 8;
  1677.         }
  1678.     }
  1679.     /* set form for first display */
  1680.     physdial[PHYSOK].ob_state = NORMAL;
  1681.     physdial[PHYSCN].ob_state = NORMAL;
  1682.     physdial[SLBOX].ob_y = 0;
  1683.     if (ndevs <= 4)    {
  1684.         physdial[SLBOX].ob_height = physdial[SLTRK].ob_height;
  1685.     } else {
  1686.         physdial[SLBOX].ob_height = physdial[SLTRK].ob_height / (ndevs/4.0);
  1687.     }
  1688.     for (i=0; i < 4; i++)    {
  1689.         physdial[physxlat[i]].ob_state = NORMAL;
  1690.         physdial[physid[i]].ob_state = NORMAL;
  1691.     }
  1692.     ok2draw = 0;
  1693.     drawdev(index);    /* draw the devices into the dialog box */
  1694.     ARROW_MOUSE;
  1695.     dsplymsg(physdial);
  1696.     ++ok2draw;
  1697.     while (xrun)     {
  1698.         switch (ret=form_do(physdial, -1))     {
  1699.             case PHYSOK:xrun = 0;
  1700.                         break;
  1701.             case PHYSCN:xrun = 0;            /* return */
  1702.                         break;
  1703.             case SLTRK: if (ndevs > 5)    {
  1704.                             scrupdn(ROLL4, &index);
  1705.                         }
  1706.                         break;
  1707.             case SLUP:  if (index != 0)    {
  1708.                             scrupdn(ROLL1, &index);
  1709.                         }
  1710.                         break;
  1711.             case SLDN:  if ((index < 12) && (index+4 < ndevs))    {
  1712.                             scrupdn(ROLL1, &index);
  1713.                         }
  1714.                         break;
  1715.             case SLBOX: if (ndevs > 5)    {
  1716.                             slidebox(physdial, &index);
  1717.                         }
  1718.                         break;
  1719.             case DRVID0:physdial[UNIT0].ob_state = SELECTED;
  1720.                        objc_draw(physdial,UNIT0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1721.                         break;;
  1722.             case DRVID1:physdial[UNIT1].ob_state = SELECTED;
  1723.                        objc_draw(physdial,UNIT1, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1724.                         break;;
  1725.             case DRVID2:physdial[UNIT2].ob_state = SELECTED;
  1726.                        objc_draw(physdial,UNIT2, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1727.                         break;;
  1728.             case DRVID3:physdial[UNIT3].ob_state = SELECTED;
  1729.                        objc_draw(physdial,UNIT3, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1730.                         break;;
  1731.             case UNIT0:physdial[DRVID0].ob_state = SELECTED;
  1732.                        objc_draw(physdial,DRVID0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1733.                         break;;
  1734.             case UNIT1:physdial[DRVID1].ob_state = SELECTED;
  1735.                        objc_draw(physdial,DRVID1, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1736.                         break;;
  1737.             case UNIT2:physdial[DRVID2].ob_state = SELECTED;
  1738.                        objc_draw(physdial,DRVID2, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1739.                         break;;
  1740.             case UNIT3:physdial[DRVID3].ob_state = SELECTED;
  1741.                        objc_draw(physdial,DRVID3, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1742.                         break;;
  1743.           }
  1744.       }
  1745.  
  1746.   /*
  1747.    * Draw shrinking box and cleanup the screen;
  1748.    * return thing that caused our exit.
  1749.    */
  1750.     erasemsg();
  1751.  
  1752.     if (ret == PHYSCN)    {
  1753.         return ERROR;
  1754.     }
  1755.     /* search for the selected unit */
  1756.     for (i=0; i < 4; i++)    {
  1757.         if (physdial[physxlat[i]].ob_state & SELECTED)    {
  1758.             if (tformat)    {
  1759.                 return(index+tpdev+i);
  1760.             } else {
  1761.                 return(devid[index+i].dev);
  1762.             }
  1763.         }
  1764.     }
  1765.     return ERROR;
  1766. }
  1767.  
  1768. /* draw the select devices dialog box for the format operation */
  1769.  
  1770. fdrawdev(index)
  1771. int index;
  1772. {
  1773.  
  1774.     int i, st=0;
  1775.  
  1776.     if ((spscsixst)    || (atexst))    {
  1777.         st = 8;
  1778.     }
  1779.     
  1780.     for (i=0; i < 4; i++)    {
  1781.         /*
  1782.         (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[36][0];
  1783.         (physdial[physid[i]].ob_spec)->te_ptext = &drvid[36][0];
  1784.         */
  1785.         if (i+index+st < 8)    {
  1786.               (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[19+i+index][0];
  1787.         } else if (i+index+st < 16)    {
  1788.         (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[27+i+index+st-8][0];
  1789.         } else {
  1790.             (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[35][0];
  1791.         }
  1792.         physdial[physxlat[i]].ob_state = NORMAL;
  1793.         physdial[physid[i]].ob_state = NORMAL;
  1794.         if (i+index+st == 16)    {    /* it is sparrow */
  1795.             (physdial[physid[i]].ob_spec)->te_ptext = &drvid[i+index+st][0];
  1796.         } else if (livedevs[i+index+st])    {
  1797.             if (idevs[i+index+st])    {
  1798.                 (physdial[physid[i]].ob_spec)->te_ptext = &drvid[i+index+st][0];
  1799.             } else {
  1800.                 (physdial[physid[i]].ob_spec)->te_ptext = &drvid[17][0];
  1801.             }
  1802.         } else {
  1803.             if (idevs[i+index+st])    {
  1804.                 (physdial[physid[i]].ob_spec)->te_ptext = &drvid[i+index+st][0];
  1805.             } else {
  1806.                 (physdial[physid[i]].ob_spec)->te_ptext = &drvid[18][0];
  1807.             }
  1808.             /*
  1809.             physdial[physid[i]].ob_state = NORMAL;
  1810.             */
  1811.         }
  1812.         if (ok2draw)    {
  1813.             /*
  1814.             objc_draw(physdial,physlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  1815.             */
  1816.             objc_draw(physdial,physxlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  1817.             objc_draw(physdial,physid[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  1818.         }
  1819.     }
  1820. }
  1821.     
  1822. /* draw the select devices dialog box for the partition operation */
  1823.  
  1824. drawdev(index)
  1825. int index;
  1826. {
  1827.  
  1828.     int i, j;
  1829.  
  1830.     if (tformat)    {
  1831.         fdrawdev(index);
  1832.         return OK;
  1833.     }
  1834.  
  1835.     for (i=0; i < 4; i++)    {
  1836.         (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[36][0];
  1837.         (physdial[physid[i]].ob_spec)->te_ptext = &drvid[36][0];
  1838.         if (devid[i+index].flg)    {
  1839.                physdial[physxlat[i]].ob_state = NORMAL;
  1840.                physdial[physid[i]].ob_state = NORMAL;
  1841.             /*
  1842.             if (devid[i+index].flg == 2)    {
  1843.                 physdial[physxlat[i]].ob_state = NORMAL;
  1844.             } else {
  1845.                 physdial[physxlat[i]].ob_state = NORMAL | OUTLINED;
  1846.             }
  1847.             */
  1848.             j = devid[i+index].dev;
  1849.             if (j < 8)    {
  1850.                 /*
  1851.                 drvid[19][10] = devid[i+index].dev + '0';
  1852.                 */
  1853.                 (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[19+j][0];
  1854.             } else if (j < 16)    {
  1855.                 /*
  1856.                 drvid[20][10] = devid[i+index].dev - 8 + '0';
  1857.                 */
  1858.                 (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[27+j-8][0];
  1859.             } else {
  1860.                 (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[35][0];
  1861.             }
  1862.             /*
  1863.             physdial[physid[i]].ob_state = NORMAL;
  1864.             */
  1865.             (physdial[physid[i]].ob_spec)->te_ptext = devid[i+index].id;
  1866.         } else {
  1867.             physdial[physxlat[i]].ob_state = DISABLED;
  1868.             physdial[physid[i]].ob_state = DISABLED;
  1869.             /*
  1870.             (physdial[physid[i]].ob_spec)->te_ptext = &drvid[18][0];
  1871.             */
  1872.         }
  1873.         if (ok2draw)    {
  1874.             objc_draw(physdial,physxlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  1875.             objc_draw(physdial,physid[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  1876.             /*
  1877.             objc_draw(physdial,physlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  1878.             */
  1879.         }
  1880.     }
  1881. }
  1882.  
  1883. scrupdn(roll, index)
  1884. int roll;
  1885. int *index;
  1886.  
  1887. {
  1888.      int gr_mkmx, gr_mkmy;
  1889.     int gr_mkmstate, gr_mkkstate;
  1890.     int barht, barx, bary;
  1891.     int eptx, epty, eptht;
  1892.  
  1893.     barht = physdial[SLTRK].ob_height;
  1894.     eptht = physdial[SLBOX].ob_height;
  1895.     graf_mkstate(&gr_mkmx, &gr_mkmy, &gr_mkmstate, &gr_mkkstate);
  1896.     objc_offset(physdial, SLBOX, &eptx, &epty);
  1897.     objc_offset(physdial, SLTRK, &barx, &bary);
  1898.     /* check which part of bar was clicked */
  1899.     if (gr_mkmy > (epty+eptht))    {    /* low part of bar was clicked */
  1900.         if (roll == ROLL4)    {
  1901.             /*
  1902.             if (eptht > (bary+barht-epty-eptht))    {
  1903.             if (((spscsixst)||(atexst)) && (*index+5 >= ndevs))    {
  1904.                 *index = ndevs - 4;
  1905.                 physdial[SLBOX].ob_y = barht - eptht;
  1906.             } else if (*index+5 >= ndevs)    {
  1907.             */
  1908.             if ((*index+5 >= ndevs) || (eptht > (bary+barht-epty-eptht)))    {
  1909.                 physdial[SLBOX].ob_y = barht - eptht;
  1910.                 *index = ndevs - 4;    /* the last 4 to display */
  1911.             } else if (*index+4 < ndevs)    {
  1912.                 /*
  1913.                 physdial[SLBOX].ob_y += barht / 4;
  1914.                 */
  1915.                 physdial[SLBOX].ob_y += eptht;
  1916.                 *index += 4;
  1917.             }
  1918.         } else {    /* ROLL1 */
  1919.             if ((*index+5 >= ndevs)||((barht/ndevs)>(bary+barht-epty-eptht))){
  1920.                 physdial[SLBOX].ob_y = barht - eptht;
  1921.                 *index = ndevs - 4;    /* the last 4 to display */
  1922.             } else {
  1923.                 physdial[SLBOX].ob_y += barht / ndevs;
  1924.                 *index += 1;
  1925.             }
  1926.         }
  1927.     } else if (gr_mkmy < epty)    {    /* upper part of bar was clicked */
  1928.         if (roll == ROLL4)    {
  1929.             if ((eptht > (epty - bary)) || (*index <= 4))    {
  1930.                 physdial[SLBOX].ob_y = 0;
  1931.                 *index = 0;
  1932.             } else {
  1933.                 /*
  1934.                 physdial[SLBOX].ob_y -= barht / 4;
  1935.                 */
  1936.                 physdial[SLBOX].ob_y -= eptht;
  1937.                 *index -= 4;
  1938.             }
  1939.         } else {
  1940.             if (*index <= 1)    {
  1941.                 physdial[SLBOX].ob_y = 0;
  1942.                 *index = 0;
  1943.             } else {
  1944.                 physdial[SLBOX].ob_y -= barht / ndevs;
  1945.                 *index -= 1;
  1946.             }
  1947.         }
  1948.     } else {
  1949.       return OK;
  1950.     }
  1951.     objc_draw(physdial,SLTRK, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1952.     drawdev(*index);
  1953. }
  1954.  
  1955.  
  1956. slidebox(tree, index)
  1957.  
  1958. OBJECT *tree;
  1959. int *index;
  1960.  
  1961. {
  1962.     int gr_wreturn, eptatmax;
  1963.     int ind, tmp;
  1964.  
  1965.     ind = ndevs - 4;
  1966.     eptatmax = tree[SLTRK].ob_height - tree[SLBOX].ob_height;
  1967.     gr_wreturn = graf_slidebox(tree, SLTRK, SLBOX, 1);
  1968.     tmp = (ind * gr_wreturn) / 1000;
  1969.     if (tmp == *index)    {    /* slide box is in the same place */
  1970.         return OK;    
  1971.     } else {
  1972.         *index = tmp;
  1973.     }
  1974.     if (*index+4 > ndevs)    {
  1975.         *index = ndevs-4;
  1976.     } 
  1977.     tree[SLBOX].ob_y = (eptatmax * (*index)) / ind;
  1978.     objc_draw(tree, SLTRK, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1979.     drawdev(*index);
  1980. }
  1981.  
  1982.  
  1983.  
  1984. /* put the live device into a list */
  1985.  
  1986. linkdev()
  1987. {
  1988.  
  1989.     int i, j=0;
  1990.  
  1991.     for (i=0; i<16; i++)    {
  1992.         devid[i].flg = 0;
  1993.         devid[i].id = &drvid[18][0];
  1994.         if (livedevs[i])    {
  1995.             devid[j].flg = P_EXISTS;
  1996.             devid[j].dev = i;
  1997.             if (idevs[i])    {
  1998.                 devid[j++].id = &drvid[i][0];
  1999.             } else {
  2000.                 devid[j++].id = &drvid[17][0];
  2001.             }
  2002.         } else if (idevs[i])    {
  2003.             devid[j].flg = 2;
  2004.             devid[j].dev = i;
  2005.             devid[j++].id = &drvid[i][0];
  2006.         }
  2007.     }
  2008.     if ((spscsixst) || (atexst))    {
  2009.         devid[j].flg = P_EXISTS;
  2010.         devid[j].dev = i;
  2011.         devid[j++].id = &drvid[i][0];
  2012.     }
  2013.  
  2014.     ndevs = j;    /* number of live devices */
  2015.  
  2016. }
  2017.  
  2018. ggphysdev()
  2019. {
  2020.     int i, j, endup, start, index=0;
  2021.     int ret, unit=8;
  2022.  
  2023.     /* Set up the dialog box for SCSI or ACSI or IDE-AT driver selection */
  2024. redogphy:
  2025.     typedial[SCSIYES].ob_state = NORMAL;
  2026.     typedial[ACSIYES].ob_state = NORMAL;
  2027.     typedial[IDEYES].ob_state = NORMAL;
  2028.     if (!tformat)    {
  2029.         /* check which type of unit was selected */
  2030.         if ((!ttscsi)&&(!spscsixst)&&(noacsi))    { /* don't need select */
  2031.             index = 16;
  2032.             unit = 2;
  2033.         } else if ((!ttscsi)&&(!spscsixst)&&(!atexst))    {/* don't need select */
  2034.             ;
  2035.         } else if ((!atexst) && (noacsi))    { /* don't need select */
  2036.             index = 8;
  2037.         } else {
  2038.             if ((!ttscsi)&&(!spscsixst))    {
  2039.                 typedial[SCSIYES].ob_state = DISABLED;
  2040.             } else if (!atexst)    {
  2041.                 typedial[IDEYES].ob_state = DISABLED;
  2042.             } else if (noacsi)    {
  2043.                 typedial[ACSIYES].ob_state = DISABLED;
  2044.             }
  2045.             if ((ret = execform(typedial)) == SCSIYES)    {
  2046.                 index = 8;
  2047.             } else if (ret == IDEYES)    {
  2048.                 index = 16;
  2049.                 unit = 2;
  2050.             }
  2051.         } 
  2052.     } else {     /* do format */
  2053.         if ((ret = execform(typedial)) == SCSIYES)    {
  2054.             index = 8;
  2055.         } else if (ret == IDEYES)    {
  2056.             index = 16;
  2057.             unit = 2;
  2058.         }
  2059.     }
  2060.     /*
  2061.      * Clean up and exec object;
  2062.      * shadow devs we KNOW are there.
  2063.      */
  2064.     physdial[PHYSOK].ob_state = NORMAL;
  2065.     physdial[PHYSCN].ob_state = NORMAL;
  2066.     
  2067.     /*
  2068.     if (tformat == TRUE) {
  2069.         start = 1;        start initializing at unit 0 
  2070.         physdial[physxlat[0]].ob_state = NORMAL;
  2071.     } else {
  2072.         start = 0;        start initializing at unit 1
  2073.     }
  2074.     */
  2075.     
  2076.     endup = index + unit;
  2077.     if (index == 16)    {
  2078.         physdial[physxlat[0]].ob_state = NORMAL;
  2079.         if ((spscsixst) || (atexst))    {
  2080.             (physdial[physid[0]].ob_spec)->te_ptext = &drvid[16][0];
  2081.         } else {
  2082.             (physdial[physid[0]].ob_spec)->te_ptext = &drvid[18][0];
  2083.         }
  2084.         for (i = 1; i < 8; i++)    {
  2085.             (physdial[physid[i]].ob_spec)->te_ptext = &drvid[18][0];
  2086.             physdial[physid[i]].ob_state = DISABLED;
  2087.             physdial[physxlat[i]].ob_state = DISABLED;
  2088.         }
  2089.     } else {
  2090.         for (i = 0; i < 8; i++)    {
  2091.             (physdial[physid[i]].ob_spec)->te_ptext = &drvid[18][0];
  2092.             if ((spscsixst)&&(tformat)&&(!index))    {
  2093.                 physdial[physid[i]].ob_state = DISABLED;
  2094.                 physdial[physxlat[i]].ob_state = DISABLED;
  2095.             } else if (tformat)    {    /* when format, all devices are on */
  2096.                 physdial[physxlat[i]].ob_state = NORMAL;
  2097.                 physdial[physid[i]].ob_state = NORMAL;
  2098.             } else {
  2099.                 physdial[physid[i]].ob_state = DISABLED;
  2100.                 physdial[physxlat[i]].ob_state = DISABLED;
  2101.             }
  2102.         }
  2103.     }
  2104.     /*
  2105.     if (ttscsi)             the hard drive is a SCSI drive 
  2106.         physdial[physxlat[8]].ob_state = NORMAL;
  2107.     */
  2108.     for (i = index, j = 0; i < endup; ++i, j++)        {
  2109.         if (livedevs[i])    {
  2110.             physdial[physxlat[j]].ob_state = NORMAL | SHADOWED;
  2111.             physdial[physid[j]].ob_state = NORMAL;
  2112.             if ((i < 16) && (idevs[i]))    {
  2113.                 (physdial[physid[j]].ob_spec)->te_ptext = &drvid[i][0];
  2114.             } else if ((i < 16) && (!index))    {
  2115.                 (physdial[physid[j]].ob_spec)->te_ptext = &drvid[17][0];
  2116.             }
  2117.         }
  2118.     }
  2119.  
  2120.  
  2121.     if (execform(physdial) != PHYSOK)
  2122.         return ERROR;
  2123.      
  2124.     /* search for the selected unit */
  2125.     for (i = 0; i < unit; ++i)
  2126.         if (physdial[physxlat[i]].ob_state & SELECTED)    {
  2127.             return(index+i);
  2128.             /*
  2129.             if (livedevs[index+i])
  2130.                 return(index+i);
  2131.             else    {    
  2132.                 form_alart(1, nodev);
  2133.                 goto redogphy;
  2134.             }
  2135.             */
  2136.         }
  2137.  
  2138.  
  2139.     return ERROR;            /* if no object selected */
  2140. }
  2141.  
  2142. /*
  2143.  * Translate from logical device number
  2144.  * to object number in logical device
  2145.  * dialouge box.
  2146.  */
  2147. int logxlat[] = {
  2148.     CCOLON, DCOLON, ECOLON, FCOLON,
  2149.     GCOLON, HCOLON, ICOLON, JCOLON,
  2150.     KCOLON, LCOLON, MCOLON, NCOLON,
  2151.     OCOLON, PCOLON
  2152. };
  2153.  
  2154.  
  2155. /*
  2156.  * Get logical device,
  2157.  * return 'C'...'P'
  2158.  * or -1.
  2159.  *
  2160.  */
  2161. glogdev()
  2162. {
  2163.     int i, flg;
  2164.  
  2165.     /*
  2166.      * Setup tree; selectively enable drive buttons
  2167.      * and so on.
  2168.      */
  2169.     logdial[LOGOK].ob_state = NORMAL;
  2170.     logdial[LOGCN].ob_state = NORMAL;
  2171.     for (i = 0; i < MAXLOGDEVS; ++i) {
  2172.     if (logmap[i].lm_physdev < 0)
  2173.         flg = DISABLED;
  2174.         else flg = NORMAL;
  2175.     logdial[logxlat[i]].ob_state = flg;
  2176.     }
  2177.  
  2178.     if (execform(logdial) != LOGOK) return -1;
  2179.  
  2180.     for (i = 0; i < MAXLOGDEVS; ++i)
  2181.     if (logdial[logxlat[i]].ob_state & SELECTED)
  2182.         return i + 'C';
  2183.  
  2184.     return -1;
  2185. }
  2186.  
  2187.  
  2188. /*
  2189.  * Open virtual workstation.
  2190.  *
  2191.  */
  2192. open_vwork()
  2193. {
  2194.     int i;
  2195.  
  2196.     for (i = 0; i < 10;)
  2197.     work_in[i++] = 1;
  2198.     work_in[10] = 2;
  2199.     handle = phys_handle;
  2200.     v_opnvwk(work_in, &handle, work_out);
  2201. }
  2202.  
  2203.  
  2204. /*
  2205.  * Find and redraw all clipping rectangles
  2206.  *
  2207.  */
  2208. do_redraw(xc, yc, wc, hc)
  2209. int xc, yc, wc, hc;
  2210. {
  2211.     GRECT t1, t2;
  2212.     int temp[4];
  2213.  
  2214.     hide_mouse();
  2215.     t2.g_x=xc;
  2216.     t2.g_y=yc;
  2217.     t2.g_w=wc;
  2218.     t2.g_h=hc;
  2219.     vsf_interior(handle, 1);
  2220.     vsf_color(handle, 0);
  2221.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  2222.     while (t1.g_w && t1.g_h) {
  2223.     if (rc_intersect(&t2, &t1)) {
  2224.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  2225.         temp[0] = xwork;
  2226.         temp[1] = ywork;
  2227.         temp[2] = xwork + wwork - 1;
  2228.         temp[3] = ywork + hwork - 1;
  2229.         v_bar(handle, temp);
  2230.     }
  2231.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  2232.     }
  2233.  
  2234.     show_mouse();
  2235. }
  2236.  
  2237.  
  2238. /*
  2239.  * Hide the mouse.
  2240.  *
  2241.  */
  2242. hide_mouse()
  2243. {
  2244.     if (!hidden) {
  2245.     graf_mouse(M_OFF, 0L);
  2246.     hidden = TRUE;
  2247.     }
  2248. }
  2249.  
  2250.  
  2251. /*
  2252.  * Show the mouse.
  2253.  *
  2254.  */
  2255. show_mouse() 
  2256. {
  2257.     if (hidden) {
  2258.     graf_mouse(M_ON, 0L);
  2259.     hidden = FALSE;
  2260.     }
  2261. }
  2262.  
  2263.  
  2264. /*
  2265.  * Set clipping rectangle.
  2266.  *
  2267.  */
  2268. set_clip(x, y, w, h)
  2269. int x, y, w, h;
  2270. {
  2271.     int clip[4];
  2272.  
  2273.     clip[0] = x;
  2274.     clip[1] = y;
  2275.     clip[2] = x + w;
  2276.     clip[3] = y + h;
  2277.     vs_clip(handle, 1, clip);
  2278. }
  2279.  
  2280.  
  2281. /*
  2282.  * "Execute" form,
  2283.  * return thingy that caused the exit.
  2284.  *
  2285.  */
  2286. execform(tree)
  2287. OBJECT tree[];
  2288. {
  2289.     int thingy;
  2290.  
  2291.     ARROW_MOUSE;
  2292.     dsplymsg(tree);
  2293.     thingy = form_do(tree, 0);
  2294.     erasemsg();
  2295.     BEE_MOUSE;
  2296.     return thingy;
  2297. }
  2298.  
  2299.  
  2300. /*
  2301.  *  Display a dialogue box on the screen.
  2302.  *    Input:
  2303.  *        tree - object tree for dialogue box to be displayed.
  2304.  *    Output:
  2305.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  2306.  */
  2307. dsplymsg(tree)
  2308. OBJECT *tree;
  2309. {
  2310.     form_center(tree,&lx, &ly, &formw, &formh);
  2311.  
  2312.     /*
  2313.     sx = lx + formw / 2;
  2314.     sy = ly + formh / 2;
  2315.     */
  2316.     
  2317.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  2318.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  2319. }
  2320.  
  2321.  
  2322. /*
  2323.  *  Erase a dialogue box from the screen.
  2324.  *    Input:
  2325.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  2326.  */
  2327. erasemsg()
  2328. {
  2329.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  2330. }
  2331.  
  2332.  
  2333.  
  2334. /*
  2335.  *  Make a long (4-byte) random.
  2336.  */ 
  2337. long
  2338. longrandom()
  2339. {
  2340.     long pattern;
  2341.     
  2342.     pattern = Random();
  2343.     pattern <<= 16;
  2344.     pattern ^= Random();
  2345.     
  2346.     return (pattern);
  2347. }
  2348.  
  2349. changeid(part)
  2350. PART *part;
  2351. {
  2352.     int i;
  2353.     long psiz;
  2354.  
  2355.     for(i = 0; i < npart; i++)    {
  2356.         if (i == ext)    continue;
  2357.         if (!(part[i].p_flg & P_EXISTS)) return OK;
  2358.         if (i > 3)    {
  2359.             psiz = part[i].p_siz - ROOTSECT;
  2360.         } else {
  2361.             psiz = part[i].p_siz;
  2362.         }
  2363.         if (psiz < MB16)    {
  2364.             part[i].p_id[0] = 'G';
  2365.             part[i].p_id[1] = 'E';
  2366.             part[i].p_id[2] = 'M';
  2367.         } else {
  2368.             part[i].p_id[0] = 'B';
  2369.             part[i].p_id[1] = 'G';
  2370.             part[i].p_id[2] = 'M';
  2371.         }
  2372.     }
  2373. }
  2374.  
  2375.